package utils

// 工具包

import (
	"code.project.com/chatroom/common/message"
	"encoding/binary"
	"encoding/json"
	"fmt"
	"net"
)

// 将这些方法封装到一个结构体中
type Transfer struct {
	Conn net.Conn
	Buf  [1023 * 4]byte // 传输时,使用的缓冲
}

// readPkg 读取接受的数据包， 读取解析哭护短发送过过来的数据
func (t *Transfer) ReadPkg() (mes message.Message, err error) {
	// 如果客户端关闭了链接  conn就不会阻塞
	_, err = t.Conn.Read(t.Buf[:4]) // 没有就会阻塞
	if err != nil {
		//fmt.Println("conn.Read err:", err)
		return
	}

	// 根据 buf[:4] 转换成一个uint32类型
	var pkgLen uint32
	pkgLen = binary.BigEndian.Uint32(t.Buf[:4]) // 包的长度
	// 根据 pkgLen 来读取消息内容
	n, err := t.Conn.Read(t.Buf[:pkgLen])
	if n != int(pkgLen) || err != nil {
		fmt.Println("conn.Read failed err=", err)
		return
	}

	// 把pkg 反序列化成 message.Message
	err = json.Unmarshal(t.Buf[:pkgLen], &mes)
	if err != nil {
		fmt.Println("反序列化失败", err)
		return
	}

	return
}

// 发送数据包
func (t *Transfer) WritePkg(data []byte) (err error) {
	// 先发送一个长度刚给客户端
	var pkgLen uint32
	pkgLen = uint32(len(data))
	// var buf [4]byte
	binary.BigEndian.PutUint32(t.Buf[0:4], pkgLen)
	n, err := t.Conn.Write(t.Buf[:4])
	if n != 4 || err != nil {
		fmt.Println("发送长度信息失败!")
		return
	}

	// 发送消息本身
	n, err = t.Conn.Write(data)
	if n != int(pkgLen) || err != nil {
		fmt.Println("发送度信息失败!")
		return
	}
	return
}
